package org.scboy.common.init;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import org.apache.dubbo.config.annotation.DubboReference;
import org.scboy.common.impl.SystemConfig;
import org.scboy.coobi.utils.JarPathUtil;
import org.scboy.dbms.api.AppManager;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Configuration;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.ClassScanner;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;

/**
 * 微服务初始化
 */
@Configuration
public class AppInit implements ApplicationListener<ApplicationReadyEvent>{

	Log log=LogFactory.get();
	
	@Value("${spring.application.name}")
	String appName;

	@Value("${server.port}")
	int port;
	
	@DubboReference
	AppManager app;
	
	@Override
	public void onApplicationEvent(ApplicationReadyEvent event) {

		log.info("开始初始化微服务配置");
		
		String ip="";
		String deploymentPath = JarPathUtil.getLocation();
		try {
			InetAddress localHost=InetAddress.getLocalHost();
			ip=localHost.getHostAddress();
		} catch (UnknownHostException e) {
			log.error("无法获取服务器IP地址",e);
		}
		
		String config="";
		
		String docType="properties";
		
		String currentDir = JarPathUtil.getLocation();
		
		//检查外部properties配置
		File properties= new File(currentDir+"config"+File.separator+"application.properties");
		
		//检查外部YML配置
		File yml= new File(currentDir+"config"+File.separator+"application.yml");
		
		if(properties.exists()) {
			config=FileUtil.readUtf8String(properties);
			docType="properties";
		}else if(yml.exists()) {
			config=FileUtil.readUtf8String(yml);
			docType="yml";
		}else {
			URL urlProperties=AppInit.class.getClassLoader().getResource("application.properties");
			URL urlYml=AppInit.class.getClassLoader().getResource("application.yml");
			
			if(urlProperties!=null) {
				config=FileUtil.readString(urlProperties, Charset.defaultCharset());
				docType="properties";
			}else if(urlYml!=null) {
				config=FileUtil.readString(urlYml, Charset.defaultCharset());
				docType="yml";
			}
		}
		
		app.register(ip, port, appName, deploymentPath,config,docType);
		
		
		Set<Class<?>> scanner=ClassScanner.scanPackage();
		
		List<Map<String,Object>> configList=new ArrayList<Map<String,Object>>();
		for (Class<?> clazz : scanner) {
			
			//查找所有实现SystemConfig接口的类
			if(SystemConfig.class.isAssignableFrom(clazz)&&!clazz.equals(SystemConfig.class)) {
				try {
					//获取配置信息
					SystemConfig systemConfig=(SystemConfig)clazz.getDeclaredConstructor().newInstance();
					
					Map<String,Object> sconfig=new HashMap<String, Object>();
					sconfig.put("code", systemConfig.getCode());
					sconfig.put("appName", appName);
					sconfig.put("configName", systemConfig.getConfigName());
					sconfig.put("configValue", systemConfig.defaultValue());
					sconfig.put("inputType", systemConfig.inputType().toString().toLowerCase(Locale.ENGLISH));
					sconfig.put("inputValue", JSONUtil.toJsonStr(systemConfig.getSelectData()));
					sconfig.put("note", systemConfig.getNote());
					sconfig.put("zindex", systemConfig.getIndex());
					configList.add(sconfig);
					
				} catch (InstantiationException |IllegalAccessException | IllegalArgumentException | InvocationTargetException
						| NoSuchMethodException | SecurityException e) {
					throw new RuntimeException(e);
				}
			}
		}
		
		app.InitSystemConfig(configList);
	}
}
